const STYLES = {
  Basic: 'Streets',
  Dark: 'StreetsDark',
  Light: 'StreetsLight',
  Satellite: 'Satellite512'
};

var STYLEJSON_CACHE = {};

/**
 * 地图背景切换工具
 */
class StyleSwitchUtil {
  constructor(_map) {
    this.map = _map;
  }

  /**
   * 切换地图背景式样
   * @param {*} styleid 式样Id
   */
  switchStyle(styleid) {
    switch (styleid) {
      case 'Basic':
        this.switchBasic();
        break;
      case 'Dark':
        this.switchDark();
        break;
      case 'Light':
        this.switchLight();
        break;
      case 'Satellite':
        this.switchSatellite();
        break;
      case 'Area':
        this.switchArea();
        break;
      default:
        break;
    }
  }

  /**
   * 基础矢量图
   */
  switchBasic() {
    this._nationalArea({
      isShow: false,
      basePath: 'district_zoom'
    }).then(() => {
      this._nationalArea({
        isShow: true,
        basePath: 'district_none_zoom'
      });
    });
    this.switchNormalStyle(STYLES.Basic);
    this._hideImageLayer();
  }

  /**
   * 深色图/夜景图
   */
  switchDark() {
    this._nationalArea({
      isShow: false,
      basePath: 'district_zoom'
    }).then(() => {
      this._nationalArea({
        isShow: true,
        basePath: 'district_none_zoom'
      });
    });
    this.switchNormalStyle(STYLES.Dark);
    this._hideImageLayer();
  }

  /**
   * 亮色图
   */
  switchLight() {
    this._nationalArea({
      isShow: false,
      basePath: 'district_zoom'
    }).then(() => {
      this._nationalArea({
        isShow: true,
        basePath: 'district_none_zoom'
      });
    });
    this.switchNormalStyle(STYLES.Light);
    this._hideImageLayer();
  }

  /**
   * 影像图/卫星图
   */
  switchSatellite() {
    this._nationalArea({
      isShow: false,
      basePath: 'district_none_zoom'
    });
    this._nationalArea({
      isShow: false,
      basePath: 'district_zoom'
    });
    this._showImageLayer();
  }

  /**
   * 区域图
   */
  switchArea() {
    this._hideImageLayer();
    this._nationalArea({
      isShow: true,
      basePath: 'district_zoom'
    });
    this.switchNormalStyle(STYLES.Light);
    // RegionAreaAction.execute();
  }

  /**
   * 根据样式ID，获取样式实际请求地址
   * @private
   */
  _getStyleTruthUrl(styleid) {
    var styleUrl = `aegis://styles/aegis/${styleid}`;
    var truthUrl = this.map._requestManager.transformRequest(
      this.map._requestManager.normalizeStyleURL(styleUrl),
      'Style'
    ).url;
    return truthUrl.split('?')[0];
  }

  /**
   * 根据样式ID，获取样式配置信息
   * @private
   */
  _getStyleJson(styleid) {
    return new Promise((resolve, reject) => {
      if (STYLEJSON_CACHE[styleid]) {
        console.log('use cache');
        resolve(STYLEJSON_CACHE[styleid]);
      } else {
        var styleUrl = this._getStyleTruthUrl(styleid);
        var xmlhttp = new XMLHttpRequest();
        if (xmlhttp !== null) {
          xmlhttp.onreadystatechange = () => {
            if (xmlhttp.readyState === 4) {
              if (xmlhttp.status === 200) {
                console.log('request success', xmlhttp);
                var styleJson = JSON.parse(xmlhttp.response);
                STYLEJSON_CACHE[styleid] = styleJson;
                resolve(styleJson);
              } else {
                resolve(null);
              }
            }
          };
          xmlhttp.open('GET', styleUrl, true);
          xmlhttp.setRequestHeader('authorization', SGMap.tokenTask.getAccessToken());
          xmlhttp.send(null);
        } else {
          alert('Your browser does not support XMLHTTP.');
          reject(null);
        }
      }
    });
  }

  /**
   * 显示区域图
   * @param {*} param
   */
  _nationalArea(param) {
    //最新区域调用方式
    return new Promise((resolve) => {
      this._getStyleJson(param.basePath).then((res) => {
        if (!res) {
          console.log('fetch national area style json FAILED!!!');
          resolve();
        } else {
          if (param.basePath === 'district_zoom' || param.basePath === 'district_none_zoom') {
            if (!this.map.getSource('esri')) {
              this.map.addSource('esri', res.sources.epgis);
            }
            let list = res.layers;
            list.forEach((item) => {
              item.source = 'esri';
            });
            list.forEach((item) => {
              if (!this.map.getLayer(item.id)) {
                this.map.addLayer(item);
                if (item.type === 'fill') {
                  this.map.setPaintProperty(item.id, 'fill-opacity', 1);
                }
              }
              this.map.setLayoutProperty(item.id, 'visibility', param.isShow ? 'visible' : 'none');
            });
            var hideLayer = [
              'Province/label/default',
              'City/label/default',
              'County/label/default',
              'Ociean',
              'SouthIsland'
            ];
            hideLayer.forEach((item) => {
              if (this.map.getLayer(item)) {
                this.map.setLayoutProperty(item, 'visibility', 'none');
              }
            });
          } else {
            if (!this.map.getSource(param.basePath)) {
              this.map.addSource(param.basePath, res.sources.esri);
            }
            let list = res.layers;
            list.forEach((item) => {
              item.source = param.basePath;
            });
            list.forEach((item) => {
              if (!this.map.getLayer(item.id)) {
                this.map.addLayer(item);
              }
              this.map.setLayoutProperty(item.id, 'visibility', param.isShow ? 'visible' : 'none');
            });
          }
          resolve();
        }
      });
    });
  }

  /**
   * 切换地图式样
   * @param {String} styleid
   */
  switchNormalStyle(styleid) {
    this._getStyleJson(styleid)
      .then((res) => {
        res.layers.forEach((item) => {
          var layerid = item.id;
          if (this.map.getLayer(layerid)) {
            var layout = item.layout;
            for (let prop in layout) {
              this.map.setLayoutProperty(layerid, prop, layout[prop]);
            }

            var paint = item.paint;
            for (let prop in paint) {
              this.map.setPaintProperty(layerid, prop, paint[prop]);
            }

            var filter = item.filter;
            this.map.setFilter(layerid, filter);
          }
        });
      })
      .catch(() => {
        console.log('style:%s,not found', styleid);
        return [];
      });
  }

  /**
   * 显示影像图层
   */
  _showImageLayer() {
    this._getStyleJson(STYLES.Satellite).then((res) => {
      this.map.addLayer({
        id: 'Satellite512-Road',
        source: Object.values(res.sources)[0],
        type: 'raster',
        minzoom: 0,
        maxzoom: 20
      });
      // 移动影像图层至路网图层下面
      // if (this.map.moveLayer('Satellite512-Road')) {
      //   this.map.moveLayer('Satellite512-Road', 'Railway/1');
      // }
      if (this.map.moveLayer('Satellite512-Road') && this.map.getLayer('top-3d-polygon')) {
        this.map.moveLayer('Satellite512-Road', 'top-3d-polygon');
      }
      // 把3D建筑物图层隐藏
      if (this.map.getLayer('BUILDING')) {
        this.map.setLayoutProperty('BUILDING', 'visibility', 'none');
      }
      if (this.map.getLayer('3d-building')) {
        this.map.setLayoutProperty('3d-building', 'visibility', 'none');
      }
    });
  }

  /**
   * 隐藏影像图层
   */
  _hideImageLayer() {
    if (this.map.getLayer('Satellite512-Road')) {
      this.map.removeLayer('Satellite512-Road');
    }
    if (this.map.getSource('Satellite512-Road')) {
      this.map.removeSource('Satellite512-Road');
    }
    if (this.map.getLayer('BUILDING')) {
      this.map.setLayoutProperty('BUILDING', 'visibility', 'visible');
    }
    if (this.map.getLayer('3d-building')) {
      this.map.setLayoutProperty('3d-building', 'visibility', 'visible');
    }
  }
}

export default StyleSwitchUtil;